﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Moki.Tests;

namespace Moki.Tests.Model
{
    public interface IAccount
    {
        void Withdraw(double money);
        void Deposit(double money);
    }

    public class BankAccount : IAccount
    {

        public void Withdraw(double money)
        {
            throw new NotImplementedException();
        }

        public void Deposit(double money)
        {
            throw new NotImplementedException();
        }
    }

    public interface IBar
    {
        string BarProperty { get; set; }
        string BarMethod();
    }

    public interface IFoo 
    {
        IBar Bar { get; set; }
        IBar GetBar();
        string FooMethod();
    }

    public class MultiMockTest
    {
        public string Name {get ; set;}

        public MultiMockTest(string name)
        {
            Name = name;
        }
    }

    public class MarshallByRefTestClass : MarshalByRefObject
    { 
    
    }

    public sealed class SealedClass
    {
    
    }


    public class PartialMockTest 
    {
        public virtual int IdVirtual { get; set; }

        public virtual string NameVirtual { get; set; }

        public int Id { get; set; }

        public string Name { get; set; }

        public PartialMockTest() { }

        public PartialMockTest(int id, string name)
        {
            Id = id;
            Name = name;
        }

        public virtual string ReturnsHello
        {
            get { return "Hello";  }
        }

        public string Field;

        public PartialMockTest InnerConcreteClassField;

        private PartialMockTest _partialMockTest;

        public virtual PartialMockTest ImplementedPropertyReturnsObject
        {
            get
            {
                if (_partialMockTest == null)
                    _partialMockTest = new PartialMockTest() { IdVirtual = this.IdVirtual++ };

                return _partialMockTest;

            }
        }

        public ITests InnerInterfaceField; 
        public virtual ITests InnerInterfaceProperty { get; set; }

        public virtual string GetSomething()
        {
            return "something";
        }

        public string CallGetSomething()
        {
            return GetSomething();
        }

        public virtual string GetSomethingWithArgs(int i)
        {
            return i.ToString() ;
        }

        public string CallGetSomethingWithArgs(int i)
        {
            return GetSomethingWithArgs(i);
        }

        public virtual void Do()
        {
        
        }

        public string NonVirtualMethod()
        {
            return "non-virtual";
        } 

        public void CallDoMethod()
        {
            Do();
        }

        public virtual object GetAnyObject()
        {
            return new object();
        }

        public virtual bool OriginalReturnsTrue()
        {
            return true;
        }
    }

    public interface ITests
    {
        IFoo Foo { get; set; }
        
        string Some { get; set; }

        string Any { get; set; }

        int Id { get; set; }

        PartialMockTest InnerClassProperty { get; set; }

        string GetSomething();
        void DoSomething();
        void DoSomethingWithArgs(int x, bool b);
        string Substring(int num, string str);
        bool GetAnswer();
        string ConvertToLang(int n);
        int NeedSomeArguments(int num, string str, bool value);

    }

    public class Test
    {
        public virtual int Double(int i)
        {
            return 2 * i;
        }
    }

    public interface IDefaultValues
    {
        void Void();
        int Int();
        int PInt { get; set; }
        double Double();
        double PDouble { get; set; }
        bool Bool();
        bool PBool { get; set; }
        string String();
        string PString { get; set; }
        object Ref();
        object PRef { get; set; }
        char Char();
        char PChar { get; set; }
    }

    public interface IObserver
    {
        void Notify(object sender, EventArgs e);
    }

    public interface IObservable
    {
        event EventHandler NotifyHandler;

        void NotifyObservers();
    }

    public class Observable : IObservable
    {
        public void NotifyObservers()
        {
            NotifyHandler(this, EventArgs.Empty);
        }

        public event EventHandler NotifyHandler;
    }

    public class Screen
    {
        int updates;

        public virtual void UpdatePosition(object sender, EventArgs args)
        {
            updates++;
        }
    }

    public interface IGPS
    {
        event EventHandler PositionChanged;

        void MoveTo(int x, int y);

        double GetPositionX();
        double GetPositionY();
        double ComputeDistanceBetween(string from, string to);
    }

    public interface IBinaryTree<T>
    {
        IBinaryTree<T> Left { get; set; }
        IBinaryTree<T> Right { get; set; }
        T Value { get; set; }

        T[] GetAllDescendants();
    }
}
